Native Queries কী?
Native Queries হল কাস্টম SQL কুয়েরি যা আপনি সরাসরি জিপিএ (JPA) বা Hibernate-এর মাধ্যমে ব্যবহার করতে পারেন। স্প্রিং ডেটা জেপিএ (Spring Data JPA) স্বাভাবিকভাবে হাইবারনেট কুয়েরি ল্যাঙ্গুয়েজ (HQL) বা JPQL (Java Persistence Query Language) ব্যবহার করে ডেটাবেসের সাথে ইন্টারঅ্যাক্ট করে। তবে, কিছু ক্ষেত্রে আপনি কাস্টম SQL কুয়েরি ব্যবহার করতে চাইলে Native Queries ব্যবহার করা হয়। Native Queries স্প্রিং ডেটা জেপিএ (Spring Data JPA) বা Hibernate-এর কুয়েরি ভাষার বাইরে সরাসরি ডেটাবেসের স্ট্যান্ডার্ড SQL কুয়েরি প্রয়োগের সুযোগ দেয়।
কেন Native Queries ব্যবহার করবেন?
- Performance: কিছু ক্ষেত্রে, যখন JPQL বা HQL কার্যকরী হতে পারে না, তখন Native Queries ব্যবহার করে ডেটাবেসের জন্য বিশেষভাবে অপটিমাইজড কুয়েরি লেখা যায়, যা পারফরম্যান্স বৃদ্ধি করতে পারে।
- Complex Queries: যখন ডেটাবেসের বিশেষ ফিচার বা ফাংশন যেমন window functions, grouping বা joins ব্যবহার করতে হয়, তখন Native SQL কুয়েরি সুবিধাজনক হতে পারে।
- SQL Compatibility: যদি আপনি ডেটাবেসের কিছু বিশেষ SQL বৈশিষ্ট্য ব্যবহার করতে চান যা JPQL বা HQL সমর্থন করে না, তবে Native Queries ব্যবহার করা যায়।
Spring Boot JPA তে Native Query এর উদাহরণ
ধরা যাক, আমাদের একটি User Entity এবং UserRepository রয়েছে। আমরা Native SQL কুয়েরি ব্যবহার করে User এর নাম এবং বয়সের উপর ভিত্তি করে কাস্টম ডেটা অনুসন্ধান করব।
Step 1: User Entity ক্লাস তৈরি করা
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private int age;
// Constructors, Getters, and Setters
public User(String name, int age) {
this.name = name;
this.age = age;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Step 2: UserRepository ইন্টারফেস তৈরি করা
এখন আমরা একটি UserRepository ইন্টারফেস তৈরি করব, যেখানে Native Query ব্যবহার করা হবে। Native Query ব্যবহার করার জন্য আমরা @Query অ্যানোটেশন এবং nativeQuery = true সেট করব।
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
public interface UserRepository extends JpaRepository<User, Long> {
// Native SQL query to fetch users by age
@Query(value = "SELECT * FROM user WHERE age = ?1", nativeQuery = true)
List<User> findUsersByAge(int age);
// Native SQL query to fetch users with name starting with a given prefix
@Query(value = "SELECT * FROM user WHERE name LIKE ?1%", nativeQuery = true)
List<User> findUsersByNameStartingWith(String prefix);
}
এখানে:
- প্রথম কুয়েরি
findUsersByAge(int age)একটি Native SQL কুয়েরি ব্যবহার করেuserটেবিল থেকে নির্দিষ্ট বয়সের ব্যবহারকারী খুঁজে বের করবে। - দ্বিতীয় কুয়েরি
findUsersByNameStartingWith(String prefix)ব্যবহার করে নামের প্রিফিক্সের সাথে মেলানো ব্যবহারকারীদের খুঁজে বের করবে।
Step 3: Service ক্লাস তৈরি করা
ডেটাবেসের সাথে কাজ করার জন্য একটি UserService ক্লাস তৈরি করা হবে।
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
// Get users by age using native query
public List<User> getUsersByAge(int age) {
return userRepository.findUsersByAge(age);
}
// Get users by name starting with a given prefix using native query
public List<User> getUsersByNamePrefix(String prefix) {
return userRepository.findUsersByNameStartingWith(prefix);
}
}
Step 4: Controller ক্লাস তৈরি করা
এখন একটি UserController ক্লাস তৈরি করব, যা HTTP রিকোয়েস্ট হ্যান্ডল করবে এবং Service ক্লাসের মেথড কল করবে।
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
// Endpoint to get users by age
@GetMapping("/age/{age}")
public List<User> getUsersByAge(@PathVariable int age) {
return userService.getUsersByAge(age);
}
// Endpoint to get users by name prefix
@GetMapping("/name/{prefix}")
public List<User> getUsersByNamePrefix(@PathVariable String prefix) {
return userService.getUsersByNamePrefix(prefix);
}
}
Step 5: Spring Boot Application চালানো
এখন, অ্যাপ্লিকেশন চালানোর জন্য, @SpringBootApplication অ্যানোটেশন সহ অ্যাপ্লিকেশন ক্লাস তৈরি করতে হবে:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootJpaApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootJpaApplication.class, args);
}
}
Step 6: HTTP রিকোয়েস্ট এবং অ্যাপ্লিকেশন চালানো
এখন আপনি POSTMAN বা ব্রাউজার ব্যবহার করে HTTP রিকোয়েস্ট পাঠাতে পারেন:
Get Users by Age:
GET http://localhost:8080/users/age/25Get Users by Name Prefix:
GET http://localhost:8080/users/name/John
এখানে, প্রথম রিকোয়েস্টে age = 25 এর সকল ব্যবহারকারী ফিরিয়ে দেওয়া হবে, এবং দ্বিতীয় রিকোয়েস্টে নামের প্রিফিক্স "John" দিয়ে ব্যবহারকারী খুঁজে পাওয়া যাবে।
Native Query এর সুবিধা
- পারফরম্যান্স অপ্টিমাইজেশন: যখন আপনাকে একটি ডেটাবেসের নির্দিষ্ট বৈশিষ্ট্য ব্যবহার করতে হয়, যেমন SQL ফাংশন, window functions, joins ইত্যাদি, তখন Native Query ব্যবহার করা কার্যকর।
- SQL কাস্টমাইজেশন: যদি JPA এর কুয়েরি ল্যাঙ্গুয়েজ বা JPQL যথেষ্ট না হয় এবং ডেটাবেস স্পেসিফিক কাস্টম SQL ব্যবহার করতে চান, তাহলে Native Query ব্যবহার করা হয়।
- ডেটাবেস নির্ভরশীল ফিচার: কিছু ডেটাবেস স্পেসিফিক ফিচার যেমন Stored Procedures, Triggers ইত্যাদি শুধুমাত্র Native SQL দিয়ে অ্যাক্সেস করা সম্ভব।
Native Query এর সীমাবদ্ধতা
- প্রোডাক্টিভিটি কমানো: Native SQL ব্যবহারের ফলে JPA বা Hibernate এর অটোমেটেড ফিচার হারানো যায়, যেমন ডেটাবেসের অবজেক্ট এবং Java অবজেক্টের মধ্যে সম্পর্ক ম্যাপিং।
- ডেটাবেস নির্ভরশীলতা: Native Query এর ফলে অ্যাপ্লিকেশনটি ডেটাবেস নির্ভরশীল হয়ে পড়তে পারে, যার ফলে ডেটাবেস পরিবর্তন করা কঠিন হতে পারে।
- কোড রিডেবিলিটি: Native SQL কোডটি অনেক সময় JPQL বা HQL এর চেয়ে কম রিডেবল হতে পারে, যা টেস্টিং এবং মেইনটেন্যান্সে সমস্যা সৃষ্টি করতে পারে।
সারাংশ
Native Queries হল একটি শক্তিশালী বৈশিষ্ট্য যা Spring Boot JPA-তে সরাসরি SQL কুয়েরি ব্যবহার করার সুযোগ দেয়। এটি যখন জিপিএল (JPQL) বা Hibernate কুয়েরি ভাষা সীমিত হয়, তখন Native SQL ব্যবহার করা হয় পারফরম্যান্স অপ্টিমাইজেশন এবং কাস্টম ডেটাবেস অপারেশনগুলির জন্য। Native Queries ব্যবহার করলে আপনি ডেটাবেস স্পেসিফিক কাস্টম SQL কুয়েরি করতে পারবেন, কিন্তু এটি কিছু সীমাবদ্ধতা এবং ডেটাবেস নির্ভরশীলতার ঝুঁকি তৈরি করতে পারে।
Native Query হল একটি SQL কুয়েরি যা JPA (Java Persistence API) বা Hibernate এর মাধ্যমে ব্যবহার করা হয়, তবে এটি JPA বা Hibernate এর নিজস্ব কুয়েরি ল্যাঙ্গুয়েজ (JPQL - Java Persistence Query Language) এর পরিবর্তে আসল SQL ব্যবহার করে। Native Query ব্যবহার করে ডেভেলপাররা সরাসরি ডেটাবেসের SQL কুয়েরি লেখার মাধ্যমে জটিল কুয়েরি বা ডেটাবেস স্পেসিফিক অপারেশন সম্পাদন করতে পারেন।
Native Query এর প্রয়োজনীয়তা
Native Query ব্যবহারের প্রয়োজনীয়তা তখনই দেখা দেয় যখন JPQL অথবা HQL (Hibernate Query Language) দ্বারা কিছু জটিল ডেটাবেস অপারেশন সম্পাদন করা সম্ভব না হয় বা ডেটাবেস নির্দিষ্ট কিছু বৈশিষ্ট্য ব্যবহার করতে হয়। JPQL এবং HQL জেনেরিক কুয়েরি ভাষা, যা মূলত Java Objects এবং Entity Classes এর সাথে কাজ করে, কিন্তু এই কুয়েরি ল্যাঙ্গুয়েজের সীমাবদ্ধতা রয়েছে, বিশেষ করে যখন ডেটাবেসের বিশেষ কিছু ফিচার বা ফাংশনালিটি ব্যবহার করতে হয়।
Native Query ব্যবহারের মাধ্যমে আপনি ডেটাবেস স্পেসিফিক কুয়েরি অপ্টিমাইজেশন, ফাংশন, প্রোসিডিউর কল, বা এমন কোনো ফিচার ব্যবহার করতে পারেন যা JPQL সমর্থন করে না।
Native Query এর সুবিধা
- ডেটাবেস নির্দিষ্ট ফাংশন ব্যবহার: JPQL অনেক সময় ডেটাবেস নির্দিষ্ট ফাংশন বা বৈশিষ্ট্য সমর্থন করে না। Native Query ব্যবহার করে সরাসরি SQL কুয়েরি ব্যবহার করা যায় যা ডেটাবেসের সকল ক্ষমতা কাজে লাগাতে সহায়তা করে।
- কাস্টম এবং জটিল কুয়েরি: JPQL-এ জটিল কুয়েরি লেখার ক্ষেত্রে কিছু সীমাবদ্ধতা থাকতে পারে। Native Query ব্যবহার করে আপনি যেকোনো জটিল SQL কুয়েরি তৈরি করতে পারবেন।
- পারফরম্যান্স: কিছু ক্ষেত্রে, Native Query এর মাধ্যমে কুয়েরি অপটিমাইজ করা সম্ভব হয়, যা পারফরম্যান্স বৃদ্ধি করতে সহায়তা করে।
- Stored Procedures এবং Functions: ডেটাবেসের স্টোরড প্রসিডিউর বা ফাংশন কল করার জন্য Native Query ব্যবহৃত হয়।
Native Query ব্যবহার কিভাবে করবেন
Spring Data JPA-তে Native Query ব্যবহার করতে @Query অ্যানোটেশন এবং nativeQuery = true প্যারামিটার ব্যবহার করা হয়। যখন আপনি nativeQuery = true সেট করেন, তখন Spring Data JPA SQL কুয়েরি হিসেবে সেটি এক্সিকিউট করবে।
উদাহরণ: Native Query ব্যবহার
ধরা যাক, একটি Employee Entity আছে এবং আপনি Employee টেবিল থেকে নির্দিষ্ট শর্ত অনুযায়ী ডেটা খুঁজে বের করতে চান। নিচে একটি উদাহরণ দেখানো হলো:
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String position;
private double salary;
// Getters and Setters
}
Repository Interface-এ Native Query ব্যবহার:
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
// Native Query with nativeQuery = true
@Query(value = "SELECT * FROM Employee e WHERE e.position = :position", nativeQuery = true)
List<Employee> findByPosition(String position);
// Native Query with Named Parameters
@Query(value = "SELECT * FROM Employee e WHERE e.salary > :salary", nativeQuery = true)
List<Employee> findBySalaryGreaterThan(@Param("salary") double salary);
// Using Aggregation function with Native Query
@Query(value = "SELECT AVG(e.salary) FROM Employee e", nativeQuery = true)
double findAverageSalary();
}
এখানে:
- findByPosition: একটি Native SQL কুয়েরি যা
Employeeটেবিল থেকে নির্দিষ্টpositionঅনুসারেEmployeeরেকর্ড খুঁজে বের করবে। - findBySalaryGreaterThan: Native SQL কুয়েরি যা
salaryথেকে বড়Employeeরেকর্ডগুলো বের করবে। - findAverageSalary: একটি Native SQL কুয়েরি যা
Employeeটেবিলেরsalaryএর গড় বের করবে।
Service Layer:
@Service
public class EmployeeService {
@Autowired
private EmployeeRepository employeeRepository;
public List<Employee> getEmployeesByPosition(String position) {
return employeeRepository.findByPosition(position);
}
public List<Employee> getEmployeesBySalary(double salary) {
return employeeRepository.findBySalaryGreaterThan(salary);
}
public double getAverageSalary() {
return employeeRepository.findAverageSalary();
}
}
Controller Layer:
@RestController
@RequestMapping("/employees")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@GetMapping("/position/{position}")
public List<Employee> getEmployeesByPosition(@PathVariable String position) {
return employeeService.getEmployeesByPosition(position);
}
@GetMapping("/salary/{salary}")
public List<Employee> getEmployeesBySalary(@PathVariable double salary) {
return employeeService.getEmployeesBySalary(salary);
}
@GetMapping("/average-salary")
public double getAverageSalary() {
return employeeService.getAverageSalary();
}
}
Native Query এর ব্যবহারযোগ্য ক্ষেত্র
- SQL ফিচারের ব্যবহার: যদি ডেটাবেসের স্পেসিফিক ফিচার বা ফাংশন (যেমন,
GROUP BY,HAVING, বা ডেটাবেসের নিজস্ব ফাংশন) ব্যবহার করতে হয়, তখন Native Query ব্যবহৃত হয়। - Stored Procedures: যদি আপনি ডেটাবেসের স্টোরড প্রসিডিউর বা ফাংশন কল করতে চান, তবে Native Query প্রয়োজনীয়।
- Complex SQL Queries: খুব জটিল SQL কুয়েরি, যেমন টেবিলের মধ্যে জটিল
JOINবাUNIONঅপারেশন, যে ধরনের জটিল কুয়েরি JPQL দিয়ে করা সম্ভব নয়। - Performance Optimization: যখন কিছু অপটিমাইজড কুয়েরি বা ইনডেক্স ব্যবহারের প্রয়োজন হয় এবং JPQL তা সাপোর্ট না করে, তখন Native Query ব্যবহার করা হয়।
সারাংশ
Native Query হল Spring Data JPA-তে ডেটাবেস স্পেসিফিক কুয়েরি লিখে ডেটা অ্যাক্সেস করার একটি পদ্ধতি। এটি ডেটাবেসের শক্তিশালী এবং স্পেসিফিক ফিচার ব্যবহার করতে সাহায্য করে, যেমন স্টোরড প্রসিডিউর, কাস্টম SQL ফাংশন বা ডেটাবেস স্পেসিফিক অপারেশন। JPQL এবং HQL এর সীমাবদ্ধতা কাটিয়ে Native Query ডেটাবেসের অগ্রিম ফিচার ব্যবহার করে পারফরম্যান্স বৃদ্ধি করতে সহায়তা করে। তবে, Native Query ব্যবহারের সময় ডেটাবেসের স্পেসিফিক ফিচার সমর্থন করা উচিত এবং ডেটাবেস নির্দিষ্ট কুয়েরি ব্যবহার করলে পোর্টেবিলিটি সমস্যা হতে পারে।
স্প্রিং ডেটা জেপিএ @Query অ্যানোটেশন ব্যবহার করে কাস্টম কোয়েরি লিখতে সহায়ক একটি টুল সরবরাহ করে। এর মাধ্যমে আপনি JPQL (Java Persistence Query Language) বা Native SQL কোয়েরি ব্যবহার করতে পারেন। Native SQL কোয়েরি ব্যবহার করলে, আপনি সরাসরি ডেটাবেসের জন্য SQL কোয়েরি লিখতে পারেন, যা JPA বা JPQL এর সীমাবদ্ধতার বাইরে কাজ করে।
Native Query কি?
Native Query হল একটি SQL কোয়েরি যা সরাসরি ডেটাবেসের জন্য লেখা হয়, যা JPQL এর মতো অবজেক্ট রিলেশনাল ম্যাপিংয়ের (ORM) শর্তাবলী অনুসরণ করে না। Native Query-তে আপনি সরাসরি ডেটাবেসের টেবিল নাম, কলাম নাম ব্যবহার করতে পারেন এবং এটি JPA এর মাধ্যমে এক্সিকিউট করা যায়।
@Query অ্যানোটেশন ব্যবহার করে Native SQL কোয়েরি চালানোর জন্য আপনাকে nativeQuery = true প্যারামিটার ব্যবহার করতে হবে।
@Query অ্যানোটেশন ব্যবহার করে Native Query লেখার উদাহরণ
Step ১: Entity ক্লাস তৈরি
ধরা যাক, আমাদের একটি Employee ক্লাস রয়েছে, যা একটি ডেটাবেস টেবিল employee এর প্রতিনিধিত্ব করে।
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String department;
private double salary;
// Getters and Setters
}
এখানে, Employee ক্লাসটি employee টেবিলের ডেটা পরিচালনা করছে।
Step ২: Native Query জন্য Repository তৈরি
স্প্রিং ডেটা জেপিএ @Query অ্যানোটেশন ব্যবহার করে Native SQL কোয়েরি চালানোর জন্য, nativeQuery = true ব্যবহার করতে হবে। নিচে কিছু উদাহরণ দেখানো হয়েছে:
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
// Native SQL Query to fetch employees by department
@Query(value = "SELECT * FROM employee WHERE department = ?1", nativeQuery = true)
List<Employee> findEmployeesByDepartment(String department);
// Native SQL Query to fetch employees with salary greater than a certain value
@Query(value = "SELECT * FROM employee WHERE salary > :salary", nativeQuery = true)
List<Employee> findEmployeesWithSalaryGreaterThan(double salary);
// Native SQL Query with multiple parameters
@Query(value = "SELECT * FROM employee WHERE department = :department AND salary > :salary", nativeQuery = true)
List<Employee> findEmployeesByDepartmentAndSalary(String department, double salary);
}
Explanation:
findEmployeesByDepartment:- Native SQL কোয়েরি ব্যবহার করে
departmentএর উপর ভিত্তি করে কর্মচারীদের তথ্য ফেচ করছে। এখানে?1প্যারামিটারটি প্রথম আর্গুমেন্টdepartmentরেফারেন্স করছে।
- Native SQL কোয়েরি ব্যবহার করে
findEmployeesWithSalaryGreaterThan:- Native SQL কোয়েরি ব্যবহার করে কর্মচারীদের যা একটি নির্দিষ্ট salary এর বেশি, তা ফেচ করছে। এখানে
:salaryপ্যারামিটারটি ব্যবহার করা হয়েছে।
- Native SQL কোয়েরি ব্যবহার করে কর্মচারীদের যা একটি নির্দিষ্ট salary এর বেশি, তা ফেচ করছে। এখানে
findEmployeesByDepartmentAndSalary:- Native SQL কোয়েরি ব্যবহার করে
departmentএবংsalaryউভয়ের উপর ভিত্তি করে কর্মচারীদের তথ্য ফেচ করছে।
- Native SQL কোয়েরি ব্যবহার করে
Step ৩: Service ক্লাস তৈরি
স্প্রিং সার্ভিস ক্লাসে Repository ইনজেক্ট করে Native Query মেথডগুলো কল করা হয়।
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class EmployeeService {
@Autowired
private EmployeeRepository employeeRepository;
public List<Employee> getEmployeesByDepartment(String department) {
return employeeRepository.findEmployeesByDepartment(department);
}
public List<Employee> getEmployeesWithSalaryGreaterThan(double salary) {
return employeeRepository.findEmployeesWithSalaryGreaterThan(salary);
}
public List<Employee> getEmployeesByDepartmentAndSalary(String department, double salary) {
return employeeRepository.findEmployeesByDepartmentAndSalary(department, salary);
}
}
Step ৪: Controller ক্লাস তৈরি
স্প্রিং Controller ক্লাসে সার্ভিস মেথডগুলো কল করে এবং ডেটা ক্লায়েন্টের কাছে পাঠানো হয়।
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@GetMapping("/employees/department/{department}")
public List<Employee> getEmployeesByDepartment(@PathVariable String department) {
return employeeService.getEmployeesByDepartment(department);
}
@GetMapping("/employees/salary/{salary}")
public List<Employee> getEmployeesWithSalaryGreaterThan(@PathVariable double salary) {
return employeeService.getEmployeesWithSalaryGreaterThan(salary);
}
@GetMapping("/employees/department/{department}/salary/{salary}")
public List<Employee> getEmployeesByDepartmentAndSalary(@PathVariable String department, @PathVariable double salary) {
return employeeService.getEmployeesByDepartmentAndSalary(department, salary);
}
}
এখানে, EmployeeController ক্লাসে Native Query মেথডগুলো কল করা হয়েছে এবং ডেটা GET API মাধ্যমে রিটার্ন করা হচ্ছে।
@Query অ্যানোটেশন এবং Native Query ব্যবহারের সুবিধা
- কাস্টম কোয়েরি লেখা সহজ: Native SQL কোয়েরি ব্যবহার করে আপনি যেকোনো জটিল SQL কোয়েরি সরাসরি লিখতে পারবেন এবং JPA এর সীমাবদ্ধতা এড়াতে পারবেন।
- ডেটাবেস স্পেসিফিক অপটিমাইজেশন: Native SQL কোয়েরি ব্যবহার করলে ডেটাবেসের নির্দিষ্ট সুবিধাগুলি ব্যবহার করা যায়, যেমন ইনডেক্সিং, ডেটাবেস স্পেসিফিক ফাংশন ইত্যাদি।
- ফ্লেক্সিবিলিটি:
@Queryঅ্যানোটেশন আপনার জন্য কোয়েরি লিখতে খুব সহজ করে তোলে এবং আপনি JPQL অথবা SQL উভয়ই ব্যবহার করতে পারেন।
উপসংহার
স্প্রিং ডেটা জেপিএ @Query অ্যানোটেশন ব্যবহার করে Native Query লেখা খুবই সহজ এবং কার্যকরী। এটি স্প্রিং ডেটা জেপিএ ব্যবহারকারীদের JPA বা JPQL কোয়েরি সীমাবদ্ধতার বাইরে যেতে এবং ডেটাবেসের জন্য SQL কোয়েরি লিখতে সক্ষম করে। স্প্রিং ডেটা জেপিএ দিয়ে কাস্টম Native SQL কোয়েরি ব্যবহার করে ডেটাবেস অপারেশনগুলি আরও দ্রুত এবং কার্যকরী করা যায়।
Spring Boot JPA-তে Native Query ব্যবহার করে আপনি সরাসরি SQL কুয়েরি লিখতে পারেন। এই কুয়েরি Spring Data JPA এর মাধ্যমে ডেটাবেসে কার্যকর করা হয় এবং এটি JPQL (Java Persistence Query Language) এর পরিবর্তে সাধারণ SQL কুয়েরি হতে পারে। Native Queries সাধারণত তখন ব্যবহৃত হয় যখন আপনি JPQL দিয়ে কিছু কাস্টম বা জটিল কুয়েরি করতে পারছেন না বা যখন আপনি সরাসরি ডেটাবেসের স্ট্রাকচার এবং পারফরম্যান্স অপটিমাইজেশন সম্পর্কে আরও নিয়ন্ত্রণ চান।
Native Query এর সুবিধা:
- Performance Optimization: কিছু ডেটাবেস অপারেশন যা JPQL দিয়ে কার্যকরী নয়, তা Native SQL কুয়েরি দিয়ে দ্রুত এবং কার্যকর করা যায়।
- Complex Queries: যখন ডেটাবেসের বিশেষ ফিচার যেমন যোগদান (joins), সাবকুয়েরি ইত্যাদি প্রয়োজন হয়, তখন Native Query ব্যবহার করা সুবিধাজনক।
- Direct Database Access: আপনাকে JPQL এর সীমাবদ্ধতা ছাড়াই সরাসরি SQL কুয়েরি ব্যবহার করার সুযোগ দেয়।
Native Query তৈরি করার পদ্ধতি
Spring Data JPA-তে native SQL queries ব্যবহার করতে @Query অ্যানোটেশন ব্যবহার করা হয়, যেখানে nativeQuery = true প্যারামিটারটি সন্নিবেশ করতে হয়।
উদাহরণ: Native Query ব্যবহার করে Custom Query তৈরি
ধরা যাক, আমাদের একটি Product Entity রয়েছে এবং আমরা একটি Native SQL কুয়েরি ব্যবহার করে Product Entity এর ডেটা ফিল্টার করতে চাই।
Step 1: Entity Class
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Double price;
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
}
Step 2: Native Query Repository Interface
ProductRepository ইন্টারফেসে @Query অ্যানোটেশন ব্যবহার করে Native SQL কুয়েরি তৈরি করা হয়েছে:
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
// Native SQL Query using @Query annotation
@Query(value = "SELECT * FROM product WHERE price > :price", nativeQuery = true)
List<Product> findProductsByPriceGreaterThan(@Param("price") Double price);
// Another Native Query example using a custom SQL query with JOIN
@Query(value = "SELECT * FROM product p JOIN category c ON p.category_id = c.id WHERE c.name = :categoryName", nativeQuery = true)
List<Product> findProductsByCategoryName(@Param("categoryName") String categoryName);
}
এখানে দুটি কাস্টম Native SQL কুয়েরি তৈরি করা হয়েছে:
findProductsByPriceGreaterThan: এটি একটি Native SQL কুয়েরি যাpriceএর ভিত্তিতেProductEntity এর পণ্য নির্বাচন করে।findProductsByCategoryName: এটি একটি JOIN কুয়েরি যাProductএবংCategoryটেবিলের মধ্যে সম্পর্ক স্থাপন করে এবং নির্দিষ্ট ক্যাটেগরির নাম অনুযায়ী পণ্য নির্বাচন করে।
Step 3: Service Class
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
public List<Product> getProductsByPrice(Double price) {
return productRepository.findProductsByPriceGreaterThan(price);
}
public List<Product> getProductsByCategory(String categoryName) {
return productRepository.findProductsByCategoryName(categoryName);
}
}
Step 4: Controller Class
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/products")
public class ProductController {
@Autowired
private ProductService productService;
// Endpoint to get products by price
@GetMapping("/price")
public List<Product> getProductsByPrice(@RequestParam Double price) {
return productService.getProductsByPrice(price);
}
// Endpoint to get products by category
@GetMapping("/category")
public List<Product> getProductsByCategory(@RequestParam String categoryName) {
return productService.getProductsByCategory(categoryName);
}
}
Step 5: Running the Application
এখন, আপনি /products/price?price=100 বা /products/category?categoryName=Electronics রিকোয়েস্ট দিয়ে কাস্টম Native Query কার্যকর করতে পারবেন।
Native Query এর সাথে Parameterized Query
Spring Data JPA-তে Native SQL কুয়েরি ব্যবহার করার সময়, আপনি প্যারামিটার ব্যবহার করতে পারেন। আপনি @Param অ্যানোটেশন ব্যবহার করে কুয়েরির প্যারামিটার প্রেরণ করতে পারেন।
উদাহরণ:
@Query(value = "SELECT * FROM product WHERE price BETWEEN :minPrice AND :maxPrice", nativeQuery = true)
List<Product> findProductsByPriceRange(@Param("minPrice") Double minPrice, @Param("maxPrice") Double maxPrice);
এখানে, প্যারামিটার হিসাবে minPrice এবং maxPrice ব্যবহার করা হয়েছে, যা কুয়েরিতে @Param অ্যানোটেশন দ্বারা নির্দিষ্ট করা হয়েছে।
Native Query এর সুবিধা
- Performance Optimization: কিছু কাস্টম বা জটিল কুয়েরি JPQL এর মাধ্যমে কার্যকর করা সম্ভব নয়। Native SQL কুয়েরি ডেটাবেস অপ্টিমাইজেশন, ইনডেক্সিং এবং আরও অন্যান্য টেবিল অপারেশন পরিচালনায় সাহায্য করে।
- Complex Queries: জটিল ডেটাবেস কুয়েরি যেমন সাবকুয়েরি, জয়েন এবং গ্রুপ বাই ইত্যাদি Native SQL কুয়েরির মাধ্যমে সহজে করা যায়।
- Direct Database Access: Native Query এর মাধ্যমে সরাসরি SQL কুয়েরি ব্যবহার করা যায়, যা ডেটাবেসের টেবিল স্ট্রাকচার অনুযায়ী দ্রুত কাজ করে।
সারাংশ
Native SQL Queries Spring Data JPA-তে কাস্টম কুয়েরি তৈরি করার জন্য একটি শক্তিশালী উপায়। @Query অ্যানোটেশন ব্যবহার করে nativeQuery = true দিয়ে আপনি ডেটাবেসের সরাসরি SQL কুয়েরি লিখতে পারেন, যা জটিল ডেটাবেস অপারেশন, পারফরম্যান্স অপটিমাইজেশন এবং আরও অনেক ক্ষেত্রে কার্যকরী হয়। Native Queries ব্যবহার করে Spring Data JPA-তে সরাসরি SQL কুয়েরি কার্যকর করা সম্ভব, যা Spring Boot অ্যাপ্লিকেশনের ডেটাবেস ম্যানেজমেন্টকে আরও নমনীয় এবং দ্রুত কার্যকর করে তোলে।
Read more